
use std::collections::{HashMap as Map};

use rand;
use rand::Rng;

#[derive(Debug,Clone)]
pub struct Instance {
    pub p: u32,
    pub q: u32,
    pub r: f64,
}

#[derive(Debug,Clone)]
pub struct Repr {
    pub v:Vec<f64>,
}


// User Item 组成二部图
pub fn init(n:usize,data:&Vec<Instance>) -> (Map<u32,Repr>,Map<u32,Repr>) {

    let mut uu:Map<u32,Repr> = Map::new();
    let mut vv:Map<u32,Repr> = Map::new();

    let mut rng = rand::thread_rng();

    for i in data {
        let p = i.p;
        let q = i.q;
        if !uu.contains_key(&p) {
            let mut repr: Vec<f64> = Vec::new();
            for _ in 0..n {
                    let rr:f64 = rng.gen_range(-0.5,0.5);
                    repr.push(rr);
                }
            let r = Repr {
                v:repr,

            };
            uu.insert(p,r);
        }
        if !vv.contains_key(&q) {
            let mut repr: Vec<f64> = Vec::new();
            for _ in 0..n {
                    let rr:f64 = rng.gen_range(-0.5,0.5);
                    repr.push(rr);
                }
            let r = Repr {
                v:repr,
            };
            vv.insert(q,r);
        }
    }

    (uu,vv)
}

pub fn get_score(n:usize,p:&Repr, q:&Repr) -> f64 {
    let mut r:f64 = 0.0;
    for j in 0..n {
        r += p.v[j]*q.v[j];
    }
    r
}

pub fn get_mean(instances:&Vec<Instance>) -> f64 {
    let mut r:f64 = 0.0;
    for e in instances {
        r += e.r;
    }
    let s = instances.len() as f64;
    r/s
}
